package cn.song.config;

import java.util.List;
import java.util.concurrent.*;

/**
 * 自定义线程执行器，封装了线程池的核心功能。
 * 提供了任务提交、获取Future对象以及线程池的管理方法。
 */
public class MyThreadExecutor {

    private final ThreadPoolExecutor executor;


    /**
     * 构造函数，初始化线程池。
     */
    public MyThreadExecutor() {
        this.executor = new ThreadPoolExecutor(
                10, 30, 10,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(),
                new NamedThreadFactory("MyThreadExecutor")
        );
    }

    /**
     * 构造函数，初始化线程池。
     *
     * @param corePoolSize    核心线程数
     * @param maximumPoolSize 最大线程数
     * @param keepAliveTime   空闲线程存活时间
     */
    public MyThreadExecutor(int corePoolSize, int maximumPoolSize, int keepAliveTime) {
        this.executor = new ThreadPoolExecutor(
                corePoolSize, maximumPoolSize, keepAliveTime,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(),
                new NamedThreadFactory("MyThreadExecutor")
        );
    }

    /**
     * 提交一个Runnable任务到线程池执行。
     *
     * @param task 要执行的任务
     */
    public void submit(Runnable task) {
        executor.submit(task);
    }

    /**
     * 提交一个Callable任务到线程池执行，并返回一个Future对象。
     * 该Future对象可以用来检查任务状态或获取任务结果。
     *
     * @param task 要执行的有返回值的任务
     * @param <T>  任务返回值的类型
     * @return 包含任务结果的Future对象
     */
    public <T> Future<T> submit(Callable<T> task) {
        return executor.submit(task);
    }

    /**
     * 关闭线程池，等待所有已提交的任务完成。
     * 不再接收新的任务提交。
     */
    public void shutdown() {
        executor.shutdown();
    }

    /**
     * 立即关闭线程池并取消正在执行的任务。
     * 尝试停止所有正在执行或未开始的任务，并返回尚未执行的任务列表。
     *
     * @return 尚未执行的任务列表
     */
    public List<Runnable> shutdownNow() {
        return executor.shutdownNow();
    }

    /**
     * 内部类实现ThreadFactory接口，用于创建和命名线程。
     */
    private static class NamedThreadFactory implements ThreadFactory {
        private final String namePrefix;
        private int threadId = 1;

        /**
         * 构造函数，设置线程前缀名。
         *
         * @param prefix 线程名称前缀
         */
        public NamedThreadFactory(String prefix) {
            this.namePrefix = prefix;
        }

        /**
         * 创建并返回一个新线程。
         * 设置线程的名称、守护线程状态和优先级。
         *
         * @param r Runnable任务
         * @return 新创建的线程
         */
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, namePrefix + "-" + threadId++);
            if (t.isDaemon()) {
                t.setDaemon(false);
            }
            if (t.getPriority() != Thread.NORM_PRIORITY) {
                t.setPriority(Thread.NORM_PRIORITY);
            }
            return t;
        }
    }
}
